﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace DarwinIsDead {
   
    /// <summary>
    /// Transformation matrix that controls like a camera.  Allows a
    /// <see cref="SpriteBatch"/> to cull offscreen objects.
    /// </summary>
    public class Camera {
        private float zoom;
        private Matrix transformation;
        private Vector2 position;
        private float rotation;

       
        /// <summary>
        /// Constructs a new <see cref="Camera"/>.
        /// </summary>
        public Camera() {
            zoom = 1.0f;
            rotation = 0.0f;
            position = Vector2.Zero;
        }

        /// <summary>
        /// Retrieves or sets this <see cref="Camera"/>'s zoom factor.  Set to
        /// 1.0f by default.
        /// </summary>
        public float Zoom {
            get { return zoom; }
            set { zoom = value; }
        }

        /// <summary>
        /// Retrieves or sets this <see cref="Camera"/>'s rotation, in radians.
        /// Set to 0.0f by default.
        /// </summary>
        public float Rotation {
            get { return rotation; }
            set { rotation = value; }
        }

        /// <summary>
        /// Retrieves or sets this <see cref="Camera"/>'s position.
        /// </summary>
        /// <remarks>
        /// Note that this position refers to the center of the Camera's view.
        /// To get information about the screen's actual dimensions, refer to
        /// <see cref="Microsoft.Xna.Framework.Graphics.Viewport"/>.
        /// </remarks>
        public Vector2 Position {
            get { return position; }
            set {
                position.X = value.X;
                position.Y = value.Y;
            }
        }

        /// <summary>
        /// Sets this <see cref="Camera"/>'s position.
        /// </summary>
        /// <param name="x">New x-coordinate</param>
        /// <param name="y">New y-coordinate</param>
        public void setPosition(float x, float y) {
            position.X = x;
            position.Y = y;
        }

        /// <summary>
        /// Offsets this <see cref="Camera"/>'s position.
        /// </summary>
        /// <param name="dx">horizontal offset</param>
        /// <param name="dy">vertical offset</param>
        public void Move(float dx, float dy) {
            position.X += dx;
            position.Y += dy;
        }

        /// <summary>
        /// Offsets this <see cref="Camera"/>'s position.
        /// </summary>
        /// <param name="dp">offset vector</param>
        public void Move(Vector2 dp) {
            position.X += dp.X;
            position.Y += dp.Y;
        }

        /// <summary>
        /// Returns this <see cref="Camera"/>'s transformation matrix.
        /// </summary>
        /// <param name="gfxDevice">Reference to <see cref="GraphicsDevice"/>
        /// </param>
        /// <returns>This Camera's transformation matrix.</returns>
        public Matrix Transformation(GraphicsDevice gfxDevice) {

            int vpw = gfxDevice.Viewport.Width;
            int vph = gfxDevice.Viewport.Height;

            transformation =
                Matrix.CreateTranslation(new Vector3(-position.X, -position.Y, 0)) *
                    Matrix.CreateRotationZ(rotation) *
                    Matrix.CreateScale(new Vector3(zoom, zoom, 1)) *
                    Matrix.CreateTranslation(new Vector3( (int) Math.Round(vpw * 0.5f),
                       (int) Math.Round(vph * 0.5f), 0));

            return transformation;
        }

        /// <summary>
        /// Provides a human-readable string of this <see cref="Camera"/>'s
        /// attributes.
        /// </summary>
        /// <returns>A string</returns>
        public override string ToString() {
            return base.ToString() + "{X: " + position.X + "; Y: " + position.Y + "; Zoom: " + zoom +
                "; Rotation: " + rotation + "}";
        }
    }
}
